;;; the control panel displays a control panel on top of its children

(defpackage :panel
  (:use :cl)
  (:export :control-panel
           :*invisible-control-panel*))

(in-package :panel)

(defvar *invisible-control-panel* nil
  "Set this to non-NIL to make the control panel invisible. This is
handy when switching between debugging and production in the same
build.")

(defclass control-panel (exp:subsequence)
  ((panel :initform nil :accessor panel)
   (invisiblep :initform *invisible-control-panel* :initarg :invisiblep :accessor invisiblep)
   (extra :initform nil :initarg :extra :accessor extra)))

(defmethod exp:state-init (exp (state control-panel))
  (exp:lg 'start :index (exp:subsequence-index state))
  (with-slots (panel invisiblep) state
    (unless invisiblep
      (setf panel (make-instance 'gwee::drawer-view
                                 :title "Control Panel"
                                 :x 0
                                 :y :bottom
                                 :width 150
                                 :height 20
                                 :drawer-size 200
                                 :parent gwee:*top-view*)
            (gwee:view-needs-update-p panel) t)
      (make-instance 'gwee:column-layout
                     :background (gwee:gray 200)
                     :y 20
                     :padding 10
                     :width 150
                     :height 180
                     :parent panel
                     :subviews (list*
                                (make-instance 'gwee:row-layout
                                               :background (gwee:gray 200)
                                               :padding 5
                                               :height :minimum
                                               :subviews (list
                                                          (make-instance 'gwee:button :data "Undo"
                                                                         :click-callback (exp:dispatch-event-fn exp (exp::current-state exp) exp:click-event :source :undo))
                                                          (make-instance 'gwee:button :data "Step"
                                                                         :click-callback (exp:dispatch-event-fn exp (exp::current-state exp) exp:click-event :source :step))))
                                (make-instance 'gwee:button :data "Next Problem"
                                               :click-callback (lambda (b) (declare (ignore b)) (gwee:cancel-all-timers) (signal 'exp::onward :return t)))
                                (make-instance 'gwee:button :data "Prev Problem"
                                               :click-callback (lambda (b) (declare (ignore b)) (gwee:cancel-all-timers) (signal 'exp::backward)))
                                (make-instance 'gwee:button :data "Main Menu"
                                               :click-callback (lambda (b) (declare (ignore b)) (throw 'exp::restart nil)))
                                (loop for i in (extra state)
                                   collect (make-instance 'gwee:button
                                                          :data i
                                                          :format-function (lambda (d) (substitute #\Space #\- (string-capitalize d)))
                                                          :click-callback (lambda (b) (funcall (gwee:view-data b))))))))))

(defmethod exp:state-clean-up (exp (state control-panel))
  (exp:lg 'end)
  (unless (invisiblep state)
    (gwee:delete-view (panel state))))

(defmethod exp:state-dump append (exp (state control-panel))
  `(:extra ,(extra state)
    :invisiblep ,(invisiblep state)))
